<template>
  <div>
    <div class="relative">
      <!-- <div class="flex justify-between mb-4"> -->
      <div v-if="!props.plain" class="flex justify-between mb-4">
        <div>{{ props.title }}</div>
        <div>
          <a-button type="primary" size="small" ghost @click="openDialog">
            新建
            <template #icon>
              <PlusOutlined />
            </template>
          </a-button>
        </div>
      </div>
      <InDialog v-model:show="updateDialog" title="修改属性" class="dialog" center>
        <div class="flex flex-col gr-2">
          <InListItem theme="light" class="mb-4">
            <div>列名</div>
            <div>
              <a-input v-model:value="config.column" size="small"></a-input>
            </div>
          </InListItem>
          <div class="text-666 mx-2">值列表</div>
          <InListItem v-for="item in config.newValue" theme="light">
            <div>{{ item.key }}</div>
            <div><a-input v-model:value="item.value" size="small"></a-input></div>
          </InListItem>
        </div>
        <div class="mt-6">
          <a-button type="primary" size="small" block @click="addNewValue" v-if="updateFlag"
            >保存
          </a-button>
          <a-button type="primary" size="small" block @click="updateValue" v-else>修改</a-button>
        </div>
      </InDialog>
    </div>
    <div class="relative container">
      <table v-if="config.headers.length > 0">
        <!--  表头 -->
        <thead>
          <tr>
            <th class="thead"></th>
            <th v-for="item in config.headers" :key="item.id" @contextmenu="headerMenuEvent(item)">
              {{ item.key }}
            </th>
          </tr>
        </thead>
        <!-- 表数据 -->
        <tbody v-if="props.values && props.values.length > 0" class="contextmenu-active">
          <tr v-for="(item, key) in props.values" :key="key">
            <!-- 列名 -->
            <td @dblclick="dataMenuEvent(item, key)" @contextmenu="dataMenuEvent(item, key)">
              {{ item.column }}
            </td>
            <td v-for="v in item.data" @click="copyInfo(v)" class="relative">
              <span v-if="!!v.value">{{ v.value }}</span>
              <span v-else>空</span>
              <div v-if="v.copyState" class="absolute flex flex-s copy-state px-4">
                <CheckCircleOutlined />
                <span>复制成功</span>
              </div>
            </td>
          </tr>
        </tbody>
      </table>

      <div v-if="props.values.length == 0" class="w-100 flex flex-s">
        <div class="text-center">
          <div class="text-666 my-2" v-if="props.plain">没有数据</div>
          <div v-else class="mb-4"><InEmpty width="150" /></div>
        </div>
      </div>
    </div>

    <!-- 浮动输入框 -->
    <InFloatInput
      v-model:show="input.show"
      v-model:value="input.value"
      :node="input.node"
      @onChange="onChange"
    />

    <!-- 右键菜单 -->

    <InContextmenu
      theme="dark"
      :data="currentMenu.data"
      v-if="currentMenu.show"
      :event="currentMenu.event"
      @onClose="currentMenu.show = false"
    />
  </div>
</template>

<script setup lang="ts">
import { tableDataType, tableItemType, tableValueType } from "@/types/mode-type";
import { contextmenuType } from "@/types/project";
import { copyText } from "@/utils/utils";
import {
  CheckCircleOutlined,
  DeleteOutlined,
  EditOutlined,
  PlusOutlined
} from "@ant-design/icons-vue";
import { onMounted, ref } from "vue";
import InContextmenu from "../components/InContextmenu.vue";
import InFloatInput from "../components/InFloatInput.vue";
import InDialog from "./InDialog.vue";
import InEmpty from "./InEmpty.vue";
import InListItem from "./InListItem.vue";
const emit = defineEmits(["update:headers", "update:values"]);
const props = defineProps({
  headers: {
    type: [Array] as Array<any>
  },
  values: {
    type: [Array] as Array<any>
  },
  title: {
    type: String
  },
  /* 简洁模式，没有头部信息 */
  plain: {
    type: Boolean,
    default: false
  },
  /* 让表单只读 */
  readOnly: {
    type: Boolean,
    default: false
  }
});
const updateDialog = ref(false);
const updateFlag = ref(false);
/* 核心数据，传送到父元素 */
const config = ref({
  headers: [] as Array<tableItemType>,
  values: [] as Array<any>,
  newValue: [] as Array<any>,
  column: ""
});

/**
 * todo:小功能
 *
 */
const copyInfo = (item: any) => {
  copyText(item.value);
  item.copyState = true;

  var flag = setTimeout(() => {
    clearTimeout(flag);
    item.copyState = false;
  }, 500);
};

/**
 * todo:修改鼠标右键点出来的值
 *
 */
const updateValue = () => {
  var { index } = currentMenu.value.tempData;
  config.value.values = config.value.values.map((item, i) => {
    if (index === i) {
      item.column = config.value.column;
      item.data = config.value.newValue;
    }
    return item;
  });

  emit("update:values", config.value.values);
  updateDialog.value = false;
};
/* 添加新的值 */
const addNewValue = () => {
  var { newValue, column } = config.value;
  config.value.values.push({
    data: newValue,
    column
  });
  updateDialog.value = false;
  emit("update:values", config.value.values);
  config.value.column = "";
  resetNewValue();
};
/* 动态输入 */
const input = ref({
  show: false,
  node: undefined as any,
  value: "" as any
});
/* 修改表头 */
const onChange = (value: any) => {
  currentMenu.value.tempData.key = value;
};
const resetNewValue = () => {
  config.value.headers = props.headers;
  config.value.values = props.values;
  config.value.newValue = props.headers.map((item: tableItemType) => {
    return {
      key: item.key,
      value: "",
      id: item.id
    };
  });
};
const openDialog = () => {
  updateDialog.value = true;
  updateFlag.value = true;
  resetNewValue();
};
onMounted(() => {
  resetNewValue();
});
/**
 * todo:表头右键菜单属性
 *
 */
const headMenuConfig = [
  {
    text: "编辑",
    event: () => {
      input.value.show = true;
    },
    icon: EditOutlined
  },
  {
    /* 删除表头,同时删除数据 */
    text: "删除一列",
    event: () => {
      var headers = currentMenu.value.tempData;
      config.value.headers = config.value.headers.filter((item: tableItemType) => {
        if (item.key !== headers.key) {
          return item;
        }
      });
      config.value.values = config.value.values.filter((item: tableValueType) => {
        item.data = item.data.filter((e: any) => {
          if (e.key !== headers.key) {
            return e;
          }
        });
        if (item.data.length > 0) return item;
      });
      emit("update:headers", config.value.headers);
      emit("update:values", config.value.values);
    },
    icon: DeleteOutlined
  }
];

const currentMenu = ref<contextmenuType>({
  show: false,
  data: [],
  event: undefined,
  tempData: undefined
});

/* 表头的右键菜单 ,初始化信息*/
const headerMenuEvent = (item: tableItemType) => {
  if (props.readOnly) return;
  currentMenu.value.tempData = item;
  currentMenu.value.show = true;
  currentMenu.value.event = window.event as MouseEvent;
  currentMenu.value.data = headMenuConfig;
  var target = window.event?.target as HTMLElement;
  input.value.value = item.key;
  if (target.nodeName === "TH") {
    input.value.node = target;
  }
};

/* 数据的右键菜单 ,初始化信息*/
const dataMenuEvent = (item: tableValueType, index: number) => {
  /* 记录了当前 */
  /*
    单个value信息
  */
  if (props.readOnly) return;
  currentMenu.value.tempData = {
    index,
    item
  };
  currentMenu.value.data = dataMenu;
  currentMenu.value.show = true;
  currentMenu.value.event = window.event as MouseEvent;
  /* 给编辑栏复制列名和数据 */
  config.value.newValue = item.data.map((e: any) => {
    return {
      key: e.key,
      value: e.value,
      id: e.id
    };
  });
  config.value.column = item.column;
};

const dataMenu = [
  {
    text: "编辑",
    event: () => {
      updateDialog.value = true;
      updateFlag.value = false;
    },
    icon: EditOutlined
  },
  {
    /* 删除表头,同时删除数据 */
    text: "删除当前行",
    event: () => {
      config.value.values = config.value.values.filter((item: any) => {
        var index = item.data.findIndex((e: tableDataType) => {
          if (e === currentMenu.value.tempData.item) {
            return e;
          }
        });
        if (index < 0) {
          return item;
        }
      });
      emit("update:values", config.value.values);
    },
    icon: DeleteOutlined
  }
];
/* 右键菜单end */
</script>

<style lang="scss" scoped>
.container {
  border: 1px solid #666;
}
table {
  width: 100%;
  font-size: 12px;
  td,
  th {
    text-align: center;
    border: 1px solid #666;
    overflow: hidden;
    white-space: nowrap;
    text-overflow: ellipsis;
    min-width: 40px;
  }
  thead {
    background-color: #555;
  }
  th {
    padding: 2px 0;
  }
  td {
    padding: 4px 0;
    color: #999;
    &:hover {
      cursor: pointer;
    }
  }
  tbody {
    tr {
      &:hover {
        background-color: #494949;
      }
    }
  }
}
.thead {
  width: 50px;
  text-overflow: ellipsis;
  white-space: nowrap;
  overflow: hidden;
}
.copy-state {
  color: #acff2f96;
  top: 0;
  width: 100%;
  height: 100%;
  left: 0;
  background-color: #494949;
  zoom: 0.8;
  span {
    margin-left: 2px;
  }
}
</style>
